<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>The source code</title>
  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  <style type="text/css">
    .highlight { display: block; background-color: #ddd; }
  </style>
  <script type="text/javascript">
    function highlight() {
      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
    }
  </script>
</head>
<body onload="prettyPrint(); highlight();">
  <pre class="prettyprint lang-js"><span id='global-property-'>/**
</span> * @ignore
 * Toolbar for KISSY.
 * @author yiminghe@gmail.com
 */
KISSY.add(&quot;toolbar&quot;, function (S, Container, DelegateChildrenExtension, ToolbarRender, Node, undefined) {
    var KeyCode = Node.KeyCode;

    function getNextEnabledItem(index, direction, self) {
        var children = self.get(&quot;children&quot;),
            count = 0,
            childrenLength = children.length;

        if (index == undefined) {
            if (direction == 1) {
                index = 0;
            } else {
                index = childrenLength - 1;
            }
            if (!children[index].get(&quot;disabled&quot;)) {
                return children[index];
            }
        }

        do {
            count++;
            index = (index + childrenLength + direction) % childrenLength;
        } while (count &lt; childrenLength &amp;&amp; children[index].get(&quot;disabled&quot;));

        if (count != childrenLength) {
            return children[index];
        }

        return null;
    }

    function afterCollapsedChange(e) {
        var self = this;
        if (e.newVal) {
            self.set(&quot;expandedItem&quot;, null);
        } else {
            self.set(&quot;expandedItem&quot;, e.target);
        }
    }

    function afterHighlightedChange(e) {
        var self = this,
            expandedItem,
            children,
            target = e.target;
        if (self !== target &amp;&amp; (target.isMenuItem || target.isButton)) {

            if (e.newVal) {
                children = self.get('children');
                if (expandedItem = self.get('expandedItem') &amp;&amp; S.inArray(target, children)) {
                    // in case collapse false modify highlightedItem
                    self.set('expandedItem', target.isMenuButton ? target : null);
                }
                self.set(&quot;highlightedItem&quot;, target);
            } else {
                if (!e.byPassSetToolbarHighlightedItem) {
                    self.set('highlightedItem', null);
                }
            }
        }
    }

    function getChildByHighlightedItem(toolbar) {
        var children = toolbar.get('children'), i, child;
        for (i = 0; i &lt; children.length; i++) {
            child = children[i];
            if (child.get('highlighted') || (child.isMenuButton &amp;&amp; !child.get('collapsed'))) {
                return child;
            }
        }
        return null;
    }

<span id='KISSY-Toolbar'>    /**
</span>     * Toolbar component for KISSY. xclass: 'toolbar'.
     * @class KISSY.Toolbar
     * @extends KISSY.Component.Container
     */
    return Container.extend([DelegateChildrenExtension], {
        _onSetHighlightedItem: function (item, e) {
            var id, itemEl,
                self = this,
                prevVal = e &amp;&amp; e.prevVal,
                children = self.get('children'),
                el = self.el;
            // only clear children's status
            if (prevVal &amp;&amp; S.inArray(prevVal, children)) {
                prevVal.set('highlighted', false, {
                    data: {
                        byPassSetToolbarHighlightedItem: 1
                    }
                });
            }
            if (item) {
                if (el.ownerDocument.activeElement != el) {
                    self.focus();
                }
                itemEl = item.el;
                id = itemEl.id;
                if (!id) {
                    itemEl.id=id = S.guid(&quot;ks-toolbar-item&quot;);
                }
                el.setAttribute(&quot;aria-activedescendant&quot;, id);
            } else {
                el.setAttribute(&quot;aria-activedescendant&quot;, &quot;&quot;);
            }
        },

        '_onSetExpandedItem': function (v, e) {
            if (e &amp;&amp; e.prevVal) {
                e.prevVal.set('collapsed', true);
            }
            if (v) {
                v.set('collapsed', false);
            }
        },

<span id='KISSY-Toolbar-method-bindUI'>        /**
</span>         * Protected.
         */
        bindUI: function () {
            var self = this;
            self.on(&quot;afterCollapsedChange&quot;, afterCollapsedChange, self);
            self.on(&quot;afterHighlightedChange&quot;, afterHighlightedChange, self);
        },

        handleBlurInternal: function (e) {
            var self = this,
                highlightedItem,
                expandedItem;
            self.callSuper(e);
            self.set(&quot;expandedItem&quot;, null);
            // clear for afterHighlightedChange
            if (highlightedItem = self.get(&quot;highlightedItem&quot;)) {
                highlightedItem.set('highlighted', false);
            }
        },

        getNextItemByKeyDown: function (e, current) {
            var self = this,
                orientation = self.get(&quot;orientation&quot;),
                children = self.get(&quot;children&quot;),
                childIndex = current &amp;&amp; S.indexOf(current, children);

            if (current) {
                if (current.handleKeyDownInternal(e)) {
                    return true;
                }
            }

            // Do not handle the key event if any modifier key is pressed.
            if (e.shiftKey || e.ctrlKey || e.metaKey || e.altKey) {
                return false;
            }

            // Either nothing is highlighted, or the highlighted control didn't handle
            // the key event, so attempt to handle it here.
            switch (e.keyCode) {
                case KeyCode.ESC:
                    self.view.getKeyEventTarget().fire(&quot;blur&quot;);
                    return true;

                case KeyCode.HOME:
                    current = getNextEnabledItem(undefined, 1, self);
                    break;

                case KeyCode.END:
                    current = getNextEnabledItem(undefined, -1, self);
                    break;

                case KeyCode.UP:
                    current = getNextEnabledItem(childIndex, -1, self);
                    break;

                case KeyCode.LEFT:
                    current = getNextEnabledItem(childIndex, -1, self);
                    break;

                case KeyCode.DOWN:
                    current = getNextEnabledItem(childIndex, 1, self);
                    break;

                case KeyCode.RIGHT:
                    current = getNextEnabledItem(childIndex, 1, self);
                    break;

                default:
                    return false;
            }
            return current;
        },

        handleKeyDownInternal: function (e) {
            var self = this,
                currentChild = getChildByHighlightedItem(self),
                nextHighlightedItem = self.getNextItemByKeyDown(e, currentChild);

            if (typeof nextHighlightedItem == 'boolean') {
                return nextHighlightedItem;
            }

            if (nextHighlightedItem) {
                nextHighlightedItem.set(&quot;highlighted&quot;, true);
            }

            return true;
        }

    }, {
        xclass: 'toolbar',
        ATTRS: {
            // 当前的高亮项
            highlightedItem: {},
            // 当前的扩展项，切换高亮项时如要把以前的扩展项收起，并展开当前的高亮项
            expandedItem: {},
            defaultChildCfg: {
                value: {
                    xclass: 'button',
                    handleMouseEvents: false,
                    focusable: false
                }
            },
            xrender: {
                value: ToolbarRender
            }
        }
    });
}, {
    requires: ['component/container',
        'component/extension/delegate-children',
        'toolbar/render',
        'node']
});</pre>
</body>
</html>
